package com.gopay.bis.ccb.bcdl.operation;
import com.gopay.common.constants.bank.CcbConstants;
import com.gopay.common.domain.bank.ccb.bcdl.BaseReqBody;
import com.gopay.common.domain.bank.ccb.bcdl.querydcc.req.TransReqQuerydcc6WY101;
import com.gopay.common.domain.bank.ccb.bcdl.querydcc.res.TransResQueryBody6WY101;
import com.gopay.common.domain.bank.ccb.bcdl.querydcc.res.TransResQueryListDetailInfo6WY101;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.DateUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import com.gopay.common.util.ReadWrite;
import com.gopay.common.util.SendMail;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.mapper.MapperWrapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.mail.MessagingException;

public class CcbBcdlCorpDccQueryHelper extends CcbBcdlBaseHelper<TransResQueryBody6WY101> {

    protected final static Logger logger = LoggerFactory.getLogger(CcbBcdlCorpDccQueryHelper.class);
    //存放路径
    private String configExcelPath;

    /**
     * （6WY101）一点接入活期账户明细查询
     *
     * @param req                 ssj
     * @param bcdlSocketTransport
     * @return
     * @throws GopayException
     */
    public TransResQueryBody6WY101 query(BaseReqBody req, SocketTransport bcdlSocketTransport) throws GopayException {
        //获取时间查询的类型
        TransReqQuerydcc6WY101 dcc6WY101 = (TransReqQuerydcc6WY101) req.getTrans();
        logger.info("CcbBcdlCorpDccQueryHelper 接收到的参数打印-----" + dcc6WY101.toString());
        BaseReqBody reqs = req;
        reqs.setTxCode("6WY101");
        BaseReqBody dcc101body = null;
        TransResQueryBody6WY101 body = null;
        String excel_Path = configExcelPath + DateUtils.format(new Date(), "yyyy-MM-dd") + "/";
        String fileNameExcel = "CCB_DCBL_" + dcc6WY101.getStartdate() + "_" + getGregorianCalendar() + "_" + dcc6WY101.getDateType() + ".xls"; //文件名
        String fileNameTxt = "CCB_DCBL_" + dcc6WY101.getStartdate() + "_" + getGregorianCalendar() + "_" + dcc6WY101.getDateType() + ".txt"; //文件名
        String fileNamePathExcel = excel_Path + fileNameExcel;
        String fileNamePathTxt = excel_Path + fileNameTxt;
        if (dcc6WY101.getCc() == null || dcc6WY101.getReceiver() == null) {
            logger.info("CcbBcdlCorpDccQueryHelper 收件人或 抄送人为空不能发送直接返回");
            return null;
        }
        //先判断exce是否存在,存在则直接发送邮件,不需要调用查询银行接口
        if (getExcel(dcc6WY101, fileNamePathExcel, fileNamePathTxt, excel_Path, fileNameExcel) == true) {
            logger.info("CcbBcdlCorpDccQueryHelper 直接发送,早已生成excel格式数据信息");
            body=new TransResQueryBody6WY101();
            body.setReturnCode(CcbConstants.BCDL_RESULT_CODE_SUCC);
            return body;
        }
        int size = 0;
        if (dcc6WY101.getQuerySize() != 0) {
            for (int j = 0; j <= dcc6WY101.getQuerySize(); j++) {
                String xml = getXml(reqs);
                logger.info("CcbBcdlCorpDccQueryHelper query  发送: xml = " + xml);
                bcdlSocketTransport.setHost(req.getUrl());
                String resXml = (String) bcdlSocketTransport.submit(xml);
//            logger.info("CcbBcdlCorpDccQueryHelper query 返回 :resXml = " + resXml);
                if (StringUtils.isNotBlank(resXml)) {
                    body = parse(resXml);
                    if (body != null) {
                        if (!CcbConstants.BCDL_RESULT_CODE_SUCC.equals(body.getReturnCode())) {
                            logger.error("CcbBcdlCorpDccQueryHelper error  RequestSn= " + req.getRequestSn() + "rspcod =" + body.getReturnCode() + ", returnMsg =" + body.getReturnMsg());
                        }
                        size += body.getInfo().getDetaillist().getDetaillist().size();
                        logger.info("CcbBcdlCorpDccQueryHelper 建设银行返回报文的总条数--size=" + size);
                        //创建txt文件
                        ReadWrite.write(excel_Path, fileNamePathTxt, resXml + ",/-/");
                        logger.info("记事本存目录:" + fileNamePathTxt);
                        if (body.getInfo().getDetaillist().getDetaillist().size() < 200) {
                            //组装数据包装成excel格式
                            exportFeedBack(excel_Path, fileNamePathExcel, fileNameExcel, fileNamePathTxt);
                            logger.info("CcbBcdlCorpDccQueryHelper 组装数据包装成excel格式完成 ,开始发送邮件--------------");
                            sendMessage((TransReqQuerydcc6WY101) req.getTrans(), fileNameExcel, excel_Path);
                            body.setReturnCode(CcbConstants.BCDL_RESULT_CODE_SUCC);
                            return body;
                        }
                        //数据转换
                        dcc101body = convertQuer6WY101(reqs, body);
                        TransReqQuerydcc6WY101 dcc101 = (TransReqQuerydcc6WY101) dcc101body.getTrans();
                        //每次循环给页数赋值
                        reqs = dcc101body;
                        logger.info("CcbBcdlCorpDccQueryHelper 建设银行数据查询执行到第" + dcc101.getPage() + " 页------------");
                    } else {
                        logger.error("CcbBcdlCorpDccQueryHelper parse error  RequestSn= " + req.getRequestSn());
                    }
                } else {
                    logger.error("CcbBcdlCorpDccQueryHelper resXml is null  RequestSn= " + req.getRequestSn());
                }

            }
        }
        throw new GopayException();
    }



    private  boolean  getExcel(TransReqQuerydcc6WY101 sendmain, String fileNamePathExcel, String fileNamePathXML, String excel_Path, String fileNameExcel) {
        //先判断exce是否存在,存在则直接发送邮件,不需要调用查询银行接口
        File file = new File(fileNamePathExcel);
        //先判断txt是否存在,存在则直接发送邮件,不需要调用查询银行接口
        File fileXml = new File(fileNamePathXML);
        if (fileXml.exists()) {
            if (!file.exists()) {
                //组装数据包装成excel格式
                exportFeedBack(excel_Path, fileNamePathExcel, fileNameExcel, fileNamePathXML);
            }
            sendMessage(sendmain, fileNameExcel, excel_Path);
            logger.info("CmbBcdlServiceImpl  直接发送,早已生成excel格式数据信息");
            return  true;
        }
        return  false;
    }
    private void sendMessage(TransReqQuerydcc6WY101 sendmain, String fileNameExcel, String excel_Path) {

        try {
            if (sendmain != null) {
                List sendFile = new ArrayList();
                List names = new ArrayList();
                List ccList = Arrays.asList(sendmain.getCc().split(",")); //获取多个抄送人
                names.add(fileNameExcel);
                //附件标题
                String subject = "建行对账文件明细";
                logger.info("CcbBcdlCorpDccQueryHelper  fileNameExcel 路径:" + fileNameExcel + "excel_Path路径:" + excel_Path);
                // 附件内容
                String messageText = DateUtils.format(new Date(), "yyyy-MM-dd") + ": 建行对账文件请您见附件查收!" + fileNameExcel;
                for (int i = 0; i < names.size(); i++) {
                    sendFile.add(excel_Path + (String) names.get(i));
                }
                SendMail.sendMessage(sendmain.getHost(), sendmain.getSender(),
                        sendmain.getUsername(), sendmain.getPassword(),
                        sendmain.getReceiver(), subject, messageText, "text/html;charset=gb2312", ccList,
                        sendFile, names);
                logger.info("CcbBcdlCorpDccQueryHelper  建行对账明细邮件发送成功!");
            } else {
                logger.info("CcbBcdlCorpDccQueryHelper   建行对账明细邮件收件人信息为空,不发送信息!");
            }
        } catch (MessagingException e) {
            logger.error("CcbBcdlCorpDccQueryHelper 建行对账文件明细发送邮件失败!", e);
            e.printStackTrace();
            ;

        }

    }

    /**
     * 发送请求的报文 多次循环使用
     *
     * @param
     * @return
     */
    private BaseReqBody convertQuer6WY101(BaseReqBody bodyreq, TransResQueryBody6WY101 req) {

        BaseReqBody body = new BaseReqBody();
        body.setRequestSn(DateUtils.format(new Date(), "yyMMddHHmmss"));
        body.setCustId(bodyreq.getCustId());
        body.setUserId(bodyreq.getUserId());
        body.setPassword(bodyreq.getPassword());
        body.setLanguage("CN");
        body.setUrl(bodyreq.getUrl());
        body.setTxCode("6WY101");
        TransReqQuerydcc6WY101 res = new TransReqQuerydcc6WY101();

        TransReqQuerydcc6WY101 dcc101 = (TransReqQuerydcc6WY101) bodyreq.getTrans();
        res.setAccno1(dcc101.getAccno1());
        // 开始时间
        res.setStartdate(dcc101.getStartdate());
        // 结束时间
        res.setEnddate(dcc101.getEnddate());
        //  交易方向
        res.setBargain_flag("");
        // 对方账户
        res.setCheck_acc_no("");
        // 对方账户名称
        res.setCheck_acc_name("");
        // 备注
        res.setRemark("");
        // 最小金额
        res.setLow_amt("");
        // 最大金额
        res.setHigh_amt("");
        // 起始页 每次加1
        res.setPage(String.valueOf(Integer.valueOf(req.getInfo().getPage()) + 1));
        //  定位串
        res.setPoststr("");
        //每页记录数
        res.setTotal_record("200");
        // 起始明细号
        res.setDet_no("");

        body.setTrans(res);
        return body;
    }


    public static TransResQueryBody6WY101 parsetobean(String xml) {
        XStream xs = new XStream() {
            @Override
            protected MapperWrapper wrapMapper(MapperWrapper next) {
                return new MapperWrapper(next) {
                    @Override
                    public boolean shouldSerializeMember(Class definedIn,
                                                         String fieldName) {
                        if (definedIn == Object.class) {
                            return false;
                        }
                        return super
                                .shouldSerializeMember(definedIn, fieldName);
                    }
                };
            }
        };
        xs.processAnnotations(TransResQueryBody6WY101.class);
        xs.autodetectAnnotations(true);
        TransResQueryBody6WY101 body = (TransResQueryBody6WY101) xs.fromXML(xml);
        return body;
    }


    /**
     * 上午 下午转换
     *
     * @return
     */
    private String getGregorianCalendar() {
        GregorianCalendar ca = new GregorianCalendar();
        //结果为“0”是上午 结果为“1”是下午
        String AM_PM = "";
        if (ca.get(GregorianCalendar.AM_PM) == 0) {
            AM_PM = "AM";
        } else {
            AM_PM = "PM";
        }
        return AM_PM;
    }


    public String getConfigExcelPath() {
        return configExcelPath;
    }

    public void setConfigExcelPath(String configExcelPath) {
        this.configExcelPath = configExcelPath;

    }

    public  HSSFWorkbook getHSSFWorkbook(String sheetName, String[] title, String[][] values, HSSFWorkbook wb) {
        // 第一步，创建一个webbook，对应一个Excel文件
        if (wb == null) {
            wb = new HSSFWorkbook();
        }
        // 第二步，在webbook中添加一个sheet,对应Excel文件中的sheet
        HSSFSheet sheet = wb.createSheet(sheetName);
        // 第三步，在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short
        HSSFRow row = sheet.createRow(0);
        // 第四步，创建单元格，并设置值表头 设置表头居中
        HSSFCellStyle style = wb.createCellStyle();
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式

        HSSFCell cell = null;
        //创建标题
        for (int i = 0; i < title.length; i++) {
            cell = row.createCell(i);
            cell.setCellValue(title[i]);
            cell.setCellStyle(style);
        }
        //创建内容
        for (int i = 0; i < values.length; i++) {
            row = sheet.createRow(i + 1);
            for (int j = 0; j < values[i].length; j++) {
                row.createCell(j).setCellValue(values[i][j]);
            }
        }
        return wb;
    }

    /**
     * @param fileNamePathExcel excel路径
     * @param fileNameExcel     exce文件名称
     * @param fileNamePathTxt   记事本路径
     */
    public  void exportFeedBack(String excexPath, String fileNamePathExcel, String fileNameExcel, String fileNamePathTxt) {

        Object[] resXml = ReadWrite.read(fileNamePathTxt).toString().split(",/-/");

        List<TransResQueryBody6WY101> orderList = new ArrayList<TransResQueryBody6WY101>();
        for (Object obj : resXml) {
            if (!obj.equals("\r\n")) {
                TransResQueryBody6WY101 body = CcbBcdlCorpDccQueryHelper.parsetobean(obj.toString());
                //放入集合中去
                orderList.add(body);
            }
        }
        //文件名称
        String fileName = fileNameExcel;
        String[] title = new String[]{"账户", "账户名称", "交易时间", "借方发生额（支取）", "贷方发生额（收入）", "余额", "币种",
                "对方户名", "对方账号", "记账日期", "摘要",
                "备注", "账户明细编号-交易流水号", "企业流水号", "凭证种类", "凭证号"};
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        int size = (orderList.get(0).getInfo().getDetaillist().getDetaillist().size() * (orderList.size() - 1))
                + orderList.get(orderList.size() - 1).getInfo().getDetaillist().getDetaillist().size();
        String[][] values = new String[size][];
        int j = 0;
        for (int i = 0; i < orderList.size(); i++) {
            //将对象内容转换成string
            TransResQueryBody6WY101 body = orderList.get(i);
            //循环便利
            for (TransResQueryListDetailInfo6WY101 vo : body.getInfo().getDetaillist().getDetaillist()) {
                values[j] = new String[title.length];
                //国付宝备付金账户
                values[j][0] = (body.getInfo().getAccno1());
                //账户名称
                values[j][1] = (body.getInfo().getAcc_name());
                //交易时间
                values[j][2] = (vo.getReal_trandate() + " " + vo.getTrantime());
                //借方发生额（支取）
                if (vo.getFlag1().equals("0")) {
                    values[j][3] = (vo.getAmt());
                } else {
                    values[j][3] = ("0.00");
                }
                //贷方发生额（收入）
                if (vo.getFlag1().equals("1")) {
                    values[j][4] = (vo.getAmt());
                } else {
                    values[j][4] = ("0.00");
                }
                //余额
                values[j][5] = (vo.getAmt1());
                //人民币元
                values[j][6] = ("人民币元");
                //对方户名
                values[j][7] = (vo.getAcc_name1());
                //对方账号
                values[j][8] = (vo.getAccno2());
                //记账日期
                values[j][9] = (vo.getTrandate());
                //摘要
                values[j][10] = ("自定义");
                //备注
                values[j][11] = (vo.getDet());
                //账户明细编号-交易流水号
                values[j][12] = (vo.getDet_no() + "-" + vo.getTran_flow());
                //企业流水号
                values[j][13] = (vo.getBflow());
                //凭证种类
                values[j][14] = (vo.getCre_typ());
                //凭证号
                values[j][15] = (vo.getCre_no());
                j++;
            }
        }
        HSSFWorkbook wb = getHSSFWorkbook(fileName, title, values, null);
        //将文件存到指定位置
        try {
            File filemk = new File(excexPath);
            //创建目录
            if (!filemk.exists()) {
                filemk.mkdirs();
            }
            File file = new File(excexPath + fileName);
            OutputStream out = new FileOutputStream(file, true);
            wb.write(out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}